package com.home.common.redis.config;

import com.home.common.redis.RedisTemplate;
import com.home.common.redis.RedisUtil;
import com.home.common.redis.serializer.FastJson2JsonRedisSerializer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisPassword;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.jedis.JedisClientConfiguration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.stereotype.Component;
import redis.clients.jedis.JedisPoolConfig;

import java.time.Duration;

/**
 * Description: redis 初始化
 * Created by 王大宸 on 2020-10-06 23:49
 * Created with IntelliJ IDEA.
 */
@Component
public class RedisConfiguration {
    private static final Logger logger = LoggerFactory.getLogger(RedisConfiguration.class);

    @Autowired
    private RedisConfig redisConfig;
    @Autowired
    private RedisJedisPool jedisPool;

    /***
     * 功能说明：Jedis配置
     *
     * @author 王大宸
     * @date 2019-9-10 14:52
     * @param
     * @return org.springframework.data.redis.connection.jedis.JedisConnectionFactory
     */
    @Bean
    public JedisConnectionFactory jedisConnectionFactory() {
        RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();
        redisStandaloneConfiguration.setHostName(redisConfig.getHostName());
        redisStandaloneConfiguration.setPort(redisConfig.getPort());
        redisStandaloneConfiguration.setPassword(RedisPassword.of(redisConfig.getPassword()));
        //由于我们使用了动态配置库,所以此处省略
        //  redisStandaloneConfiguration.setDatabase(database);
        JedisClientConfiguration.JedisClientConfigurationBuilder jedisClientConfiguration = JedisClientConfiguration.builder();
        jedisClientConfiguration.connectTimeout(Duration.ofMillis(redisConfig.getTimeout()));
        return new JedisConnectionFactory(redisStandaloneConfiguration);
    }

    /***
     * 功能说明: 实例化 RedisTemplate 对象
     *
     * @author 王大宸
     * @date 2019-9-10 14:53
     * @param redisConnectionFactory
     * @return org.springframework.data.redis.core.RedisTemplate
     */
    @Bean
    public RedisTemplate functionDomainRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate redisTemplate = new RedisTemplate();
        initDomainRedisTemplate(redisTemplate, redisConnectionFactory);
        logger.info("RedisTemplate 实例化成功！");
        return redisTemplate;
    }

    /***
     * 功能说明：引入自定义序列化
     *
     * @author 王大宸
     * @date 2019-9-10 14:53
     * @param
     * @return org.springframework.data.redis.serializer.RedisSerializer
     */
    @Bean
    public RedisSerializer<Object> fastJson2JsonRedisSerializer() {
        return new FastJson2JsonRedisSerializer<Object>(Object.class);
    }

    /***
     * 功能说明：设置数据存入 redis 的序列化方式,并关闭事务
     *
     * @date 2019-9-10 14:53
     * @param redisTemplate
     * @param factory
     * @return void
     */
    public void initDomainRedisTemplate(RedisTemplate redisTemplate, RedisConnectionFactory factory) {
        //如果不配置Serializer，那么存储的时候缺省使用String，如果用User类型存储，那么会提示错误User can't cast to String！
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
        redisTemplate.setValueSerializer(fastJson2JsonRedisSerializer());
        // 关闭事务
        redisTemplate.setEnableTransactionSupport(false);
        redisTemplate.setConnectionFactory(factory);
    }

    /***
     * 功能说明：注入封装RedisTemplate
     *
     * @author 王大宸
     * @date 2019-9-10 14:53
     * @param redisTemplate
     * @return RedisUtil
     */
    @Bean(name = "redisUtil")
    public RedisUtil redisUtil(RedisTemplate redisTemplate) {
        RedisUtil redisUtil = new RedisUtil();
        redisUtil.setRedisTemplate(redisTemplate);
        logger.info("RedisUtil 注入成功！");
        return redisUtil;
    }

    /***
     * 功能说明： Redis 连接池设置
     *
     * @author 王大宸
     * @date 2020/8/3 11:55
     * @param
     * @return redis.clients.jedis.JedisPoolConfig
     */
    @Bean
    public JedisPoolConfig jedisPoolConfig() {
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        jedisPoolConfig.setBlockWhenExhausted(true);
        jedisPoolConfig.setTestOnBorrow(true);
        jedisPoolConfig.setMaxTotal(redisConfig.getMaxTotal());
        jedisPoolConfig.setMaxIdle(jedisPool.getMaxIdle());
        jedisPoolConfig.setMinIdle(jedisPool.getMinIdle());
        jedisPoolConfig.setMaxWaitMillis(1000);
        return jedisPoolConfig;
    }


}
